#include "pathological.h"


void sphere_intersect(object_t *o, ray_t *r, point_t *p)
{
	p->t = DBL_MAX;
	sphere_t *s = (sphere_t *)o;
	double osubc[3] = {r->o.x - s->c.x,r->o.y - s->c.y,r->o.z - s->c.z},
		d = sqr(r->d.x*osubc[0] + r->d.y*osubc[1] + r->d.z*osubc[2])
			- (sqr(osubc[0]) + sqr(osubc[1]) + sqr(osubc[2])) + sqr(s->r), t;
	if(d < 0) return;
	t = -(r->d.x*osubc[0] + r->d.y*osubc[1] + r->d.z*osubc[2]) - sqrt(d);
	if(t < EPSILON && (t += 2*sqrt(d)) < EPSILON) return;
	p->x = r->o.x + t*r->d.x;
	p->y = r->o.y + t*r->d.y;
	p->z = r->o.z + t*r->d.z;
	p->n.x = (p->x - s->c.x)/s->r;
	p->n.y = (p->y - s->c.y)/s->r;
	p->n.z = (p->z - s->c.z)/s->r;
	p->t = t;
	return;
}

void sphere_surface_point(point_t *p, object_t *o)
{
	sphere_t *s = (sphere_t *)o;
	float r1 = ran(), r2 = ran();
	p->x = s->c.x + s->r*(p->n.x = 2*cos(2*PI*r1)*sqrt(r2*(1 - r2)));
	p->y = s->c.y + s->r*(p->n.y = 2*sin(2*PI*r1)*sqrt(r2*(1 - r2)));
	p->z = s->c.z + s->r*(p->n.z = 1 - 2*r2);
}

void sphere_aabb(aabb_t *aabb, object_t *o)
{
	sphere_t *s = (sphere_t *)o;
	aabb->min[0] = s->c.x - s->r;
	aabb->min[1] = s->c.y - s->r;
	aabb->min[2] = s->c.z - s->r;
	aabb->max[0] = s->c.x + s->r;
	aabb->max[1] = s->c.y + s->r;
	aabb->max[2] = s->c.z + s->r;
}

